<?php

namespace App\Console\Commands;

use App\Console\Base;
use App\Models\Agent;
use App\Models\Message;
use App\Models\MoneyTransfer;
use App\Models\PartnerUser;
use App\Models\User;
use App\Services\MoneyService;
use App\Services\MoneyTransferService;
use common\enum\MoneyTransferEnum;
use common\utils\SysCode;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class TransferSupplementProcessor extends Base
{


    /**
     * 控制台命令 signature 的名称。
     *
     * @var string
     */
    protected $signature = self::PREFIX . 'transfer_supplement';

    /**
     * 控制台命令说明。
     *
     * @var string
     */
    protected $description = 'TransferSupplement';

    /**
     * 是否厅命令
     *
     * @var bool
     */
    protected $isHallCmd = true;

    const EXCEPTION_HANDLE_TYPE = [
        //1 支持订单号查询 (或者会员+时间段查询)  (补单操作自动判断返回订单号查询， 还是时间段查询结果)
        //2 手动补单
        'FG' => 2,
        'AG' => 1,//时间范围
        'HB' => 1,
        'MW' => 1,
        'OG' => 1,
        'MG' => 1,
        'CQ9' => 1,
        'GNS' => 1,
        'SB' => 1,
        'HC' => 2, //todo 电竞暂不支持？
        'BG' => 1,
        'KY' => 2,
        'LEG' => 2,
        'SG' => 1,
        'EBET' => 1,
        'LEBO' => 2,
        'BNG' => 1,
    ];

    /**
     * 执行控制台命令。
     *
     * @return mixed
     */
    public function handle()
    {
        //超过5分钟的转账， 如果不是 成功 失败 或者异常的， 则统一改为异常单 ===========================================
        try {
            $endTime = date('Y-m-d H:i:s', time() - 60 * 5);//本次获取结束时间
            $list = MoneyTransfer::select(['id'])->whereNotIn('status', [
                MoneyTransferEnum::TRANSFER_STATUS_SUCCESS,
                MoneyTransferEnum::TRANSFER_STATUS_FAILED,
                MoneyTransferEnum::TRANSFER_STATUS_EXCEPTION
            ])->where('created_at',
                '<', $endTime)->limit(1000)->get();
            if (count($list) > 0) {
                $list = $list->toArray();
                $ids = array_column($list, 'id');
                MoneyTransfer::whereIn('id', $ids)->update(['status' => MoneyTransferEnum::TRANSFER_STATUS_EXCEPTION]);
                $this->info("自动转异常单：" . json_encode($ids));
            }
        } catch (\Throwable $e) {
            $this->info("自动转异常单, 错误：" . $e->getTraceAsString());
        }


        //查询超过20秒的转账异常单 =====================================================================================
        $checkPartnerNameList = ['HB', 'MW', 'OG', 'MG', 'CQ9', 'GNS', 'SB', 'SG','HC'];//OG获取转账记录接口有频率限制？
        $endTime = date('Y-m-d H:i:s', time() - 20);//本次获取结束时间
        $count = MoneyTransfer::where('status', '=', MoneyTransferEnum::TRANSFER_STATUS_EXCEPTION)->where('created_at',
            '<', $endTime)->whereIn('money_partner_name', $checkPartnerNameList)->count();
        //分批处理
        if ($count > 0) {
            $size = 100;
            $page = ceil($count / $size);
            for ($i = 0; $i < $page; $i++) {
                $list = MoneyTransfer::where('status', '=',
                    MoneyTransferEnum::TRANSFER_STATUS_EXCEPTION)->where('created_at',
                    '<', $endTime)->orderBy('created_at', 'desc')->whereIn('money_partner_name', $checkPartnerNameList)->limit($size)->offset($i * $size)->get();
                $this->handleTransfer($list->toArray());
            }
        }
    }

    // 获取第三方游戏用户名
    public function getPartnerUsername($userId, $partnerName)
    {
        $pu = PartnerUser::where([
            'user_id' => $userId,
            'partner_name' => strtoupper($partnerName),
        ])->first();
        if ($pu) {
            return $pu->partner_username;
        }
        return null;
    }

    /**
     * 批次处理
     * @param $list
     */
    protected function handleTransfer($list)
    {
        if (empty($list)) {
            return;
        }
        $handleType = static::EXCEPTION_HANDLE_TYPE;
        foreach ($list as $val) {
            $val = (array)$val;
            $partnerName = $val['money_partner_name'];
            if (isset($handleType[$partnerName]) && $handleType[$partnerName] == 1) {//1 支持订单号查询 (或者会员+时间段查询) 的第三方
                try {
                    $partnerUserName = $this->getPartnerUsername($val['user_id'],
                        $val['money_partner_name']);
                    $orderNumber = $val['order_number'];
                    $beginTime = strtotime($val['created_at']);
                    $status = null;

                    $data = [
                        'api_name' => $partnerName,
                        'username' => $partnerUserName,
                        'order_number' => $orderNumber,
                        'begin_time' => $beginTime,
                    ];
                    $ret = MoneyService::partnerRequest('/api/checkTransferResult', 'get', $data);
                    if (isset($ret['code'])) {
                        if ($ret['code'] == SysCode::OK) {//转账成功
                            $status = MoneyTransferEnum::TRANSFER_STATUS_SUCCESS;
                        } elseif ($ret['code'] == SysCode::API_ERROR_TRANSFER_FAILED) {//转账失败
                            $status = MoneyTransferEnum::TRANSFER_STATUS_FAILED;
                        } else {//其它错误状态忽略， 继续执行时间范围查询
                            $this->info("转账异常，单号查询失败" . json_encode($ret));
                            continue;
                        }
                    }
                    //结果处理
                    $params = [
                        'money_transfer_id' => $val['id'],
                        'status' => $status,
                        'remark' => '转账异常自动处理'
                    ];
                    $ret = MoneyService::handleTransfer($params);
                    $this->info("转账异常：{$val['id']} 补单成功" . json_encode($ret));
                } catch (\Throwable $e) {
                    $this->info("转账异常，单号查询发生错误" . $e->getMessage());
                    continue;
                }
            }
        }
    }
}
